#include "dht11.h"
#include "systick.h"

/*********************
 *@brief:dht11初始化
 *@para:void
 *@return:void
 *********************/
u8 dht11_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;	
 	RCC_APB2PeriphClockCmd(dht11_GPIO_CLK, ENABLE);	 		//使能PA端口时钟
 	GPIO_InitStructure.GPIO_Pin = dht11_GPIO_PIN;			//PG11端口配置
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		//推挽输出
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(dht11_GPIO_PORT, &GPIO_InitStructure);		//初始化IO口
 	GPIO_SetBits(dht11_GPIO_PORT,dht11_GPIO_PIN);			//PG11 输出高

	dht11_Rst();			//MCU发送复位信号
	return dht11_Respond();	//返回dht11芯片的响应状态
}

/*********************
 *@brief:dht11模式设置 
						输入1表示引脚模式为输出模式，
						输入0表示引脚模式为输入模式。
 *@para:mode
 *@return:void
 *********************/
void dht11_Mode(u8 mode)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	if(mode)
	{
		GPIO_InitStructure.GPIO_Pin = dht11_GPIO_PIN;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	}
	else
	{
		GPIO_InitStructure.GPIO_Pin = dht11_GPIO_PIN;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	}
	GPIO_Init(dht11_GPIO_PORT, &GPIO_InitStructure);
}

/*********************
 *@brief:dht11复位
 *@para:void
 *@return:void
 *********************/
void dht11_Rst(void)
{	
	dht11_Mode(OUT);		//模式为输出
	dht11_LOW();			//拉低电平
	Systick_Delay_Ms(20);	//延时20ms
	dht11_HIGH();			//拉高电平
	Systick_Delay_Us(30);	//延时30ms
}

/*********************
 *@brief:dht11响应
 *@para:void
 *@return:void
 *********************/
u8 dht11_Respond(void)
{
	u8 cnt = 0;
	dht11_Mode(IN);
	//检测低电平响应时间
	while(!dht11_ReadStatus() && cnt < 100)
	{
		cnt++;
		Systick_Delay_Us(1);
	}
	if(cnt >= 100)return 1;
	else cnt = 0;
	//检测高电平响应时间
	while(dht11_ReadStatus() && cnt < 100)
	{
		cnt++;
		Systick_Delay_Us(1);
	}
	if(cnt >= 100)return 1;
	else return 0;
}

/*********************
 *@brief:dht11读取一位
 *@para:void
 *@return:void
 *********************/
u8 dht11_Read_Bit(void)
{
	u8 retry=0;
	while(GPIO_ReadInputDataBit(dht11_GPIO_PORT,dht11_GPIO_PIN)&&retry<100)//等待变为低电平
	{
		retry++;
		Systick_Delay_Us(1);
	}
	retry=0;
	while(!GPIO_ReadInputDataBit(dht11_GPIO_PORT,dht11_GPIO_PIN)&&retry<100)//等待变高电平
	{
		retry++;
		Systick_Delay_Us(1);
	}
	Systick_Delay_Us(40);//等待40us
	if(GPIO_ReadInputDataBit(dht11_GPIO_PORT,dht11_GPIO_PIN))return 1;
	else return 0;		   
}
/*********************
 *@brief:dht11读取一个字节
 *@para:void
 *@return:void
 *********************/
u8 dht11_Read_Byte(void)
{
	u8 i,dat;
	dat=0;
	for (i=0;i<8;i++) 
	{
		dat<<=1; 
		dat|=dht11_Read_Bit();
	}						    
	return dat;
}

/*********************
 *@brief:dht11读取一个字节
 *@para:void
 *@return:void
 *********************/
u8 dht11_Read_Data(u8 *temp,u8 *humi)
{
	u8 buf[5];
	u8 i;
	dht11_Rst();
	if(dht11_Respond()==0)
	{
		for(i=0;i<5;i++)//读取40位数据
		{
			buf[i]=dht11_Read_Byte();
		}
		if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
		{
			*humi=buf[0];
			*temp=buf[2];
		}
	}
	else return 1;
	return 0;	 
}
